﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace ComicsEditor
{
    public partial class BalloonControl : UserControl
    {
        private PageEditor pageEditor;
        private PageInfo pageInfo;
        private Balloon balloon;

        public BalloonControl()
        {
            InitializeComponent();
        }

        public void Activate(PageEditor pageEditor)
        {
            this.pageEditor = pageEditor;
            Visible = true;
            toolStripButtonBalloonSelect.Checked = true;
            updateCurrentBalloon();
        }

        public void Disactivate()
        {
            resetToolStripBalloon(null);
            Visible = false;
            if (balloon != null)
            {
                balloon.EndEdit();
                pageEditor.UpdatePage();
            }
        }

        public void Bind(PageInfo pageInfo)
        {
            if (balloon != null)
                balloon.EndEdit();
            balloon = null;
            updateCurrentBalloon();

            this.pageInfo = pageInfo;

            listBoxBalloons.Items.Clear();
            for (int i = 0; i < pageInfo.Balloons.Count; i++)
                listBoxBalloons.Items.Add((i + 1).ToString() + (pageInfo.Balloons[i].IsReadOnly ? " [read-only]" : ""));
            pageInfo.BalloonCreate = OnBalloonCreate;
            pageInfo.BalloonSelect = OnBalloonSelect;
        }

        public void OnBalloonCreate(Balloon balloon)
        {
            if (checkBoxFill.Checked)
                balloon.Fill = new SolidBrush(Color.FromArgb((int)(2.55*(int)numericFillOpacity.Value), labelFill.BackColor));
            else
                balloon.Fill = null;
            if (checkBoxStroke.Checked)
                balloon.Stroke = new Pen(Color.FromArgb((int)(2.55*(int)numericStrokeOpacity.Value), labelStroke.BackColor), (float)numericStroke.Value);
            else
                balloon.Stroke = null;
            balloon.CurveSmooth = Math.PI*(16 - trackBarSmooth.Value)/16;
            balloon.CurveStep = 1 + (13 - trackBarStep.Value)*3;

            listBoxBalloons.Items.Add(pageInfo.Balloons.Count.ToString());
            listBoxBalloons.SelectedIndex = pageInfo.Balloons.Count - 1;
        }

        public void OnBalloonSelect(Balloon balloon)
        {
            listBoxBalloons.SelectedIndex = pageInfo.Balloons.IndexOf(balloon);
        }

        private void updateCurrentBalloon()
        {
            if (pageEditor == null)
                return;
            pageEditor.BalloonRect.Balloon = balloon;
            pageEditor.BalloonCircle.Balloon = balloon;
            if (checkFillRestrict.Checked)
                pageEditor.BalloonFill.Balloon = balloon;
            else
                pageEditor.BalloonFill.Balloon = null;
            if (balloon != null)
            {
                balloon.BeginEdit();
                pageEditor.UpdatePage();
            }
        }

        private void resetToolStripBalloon(ToolStripButton sender)
        {
            if (sender != toolStripButtonBalloonSelect)
                toolStripButtonBalloonSelect.Checked = false;
            if (sender != toolStripButtonBalloonFill)
                toolStripButtonBalloonFill.Checked = false;
            if (sender != toolStripButtonBalloonIncludeRect)
                toolStripButtonBalloonIncludeRect.Checked = false;
            if (sender != toolStripButtonBalloonExcludeRect)
                toolStripButtonBalloonExcludeRect.Checked = false;
            if (sender != toolStripButtonBalloonIncludeCircle)
                toolStripButtonBalloonIncludeCircle.Checked = false;
            if (sender != toolStripButtonBalloonExcludeCircle)
                toolStripButtonBalloonExcludeCircle.Checked = false;
        }

        private void toolStripButtonBalloonSelect_CheckedChanged(object sender, EventArgs e)
        {
            if (toolStripButtonBalloonSelect.Checked)
            {
                resetToolStripBalloon(toolStripButtonBalloonSelect);
                pageEditor.BalloonSelect.Enable();
            }
            else
                pageEditor.BalloonSelect.Disable();
        }

        private void toolStripButtonBalloonFill_CheckedChanged(object sender, EventArgs e)
        {
            if (toolStripButtonBalloonFill.Checked)
            {
                resetToolStripBalloon(toolStripButtonBalloonFill);
                panelBalloonFill.Visible = true;
                pageEditor.BalloonFill.Enable();
            }
            else
            {
                panelBalloonFill.Visible = false;
                pageEditor.BalloonFill.Disable();
            }
        }

        private void toolStripButtonBalloonIncludeRect_CheckedChanged(object sender, EventArgs e)
        {
            if (toolStripButtonBalloonIncludeRect.Checked)
            {
                resetToolStripBalloon(toolStripButtonBalloonIncludeRect);
                pageEditor.BalloonRect.Enable(true);
            }
            else
                pageEditor.BalloonRect.Disable();
        }

        private void toolStripButtonBalloonExcludeRect_CheckedChanged(object sender, EventArgs e)
        {
            if (toolStripButtonBalloonExcludeRect.Checked)
            {
                resetToolStripBalloon(toolStripButtonBalloonExcludeRect);
                pageEditor.BalloonRect.Enable(false);
            }
            else
                pageEditor.BalloonRect.Disable();
        }

        private void toolStripButtonBalloonIncludeCircle_CheckedChanged(object sender, EventArgs e)
        {
            if (toolStripButtonBalloonIncludeCircle.Checked)
            {
                resetToolStripBalloon(toolStripButtonBalloonIncludeCircle);
                panelBalloonCircle.Visible = true;
                pageEditor.BalloonCircle.Enable(true);
            }
            else
            {
                panelBalloonCircle.Visible = false;
                pageEditor.BalloonCircle.Disable();
            }
            pageEditor.UpdatePage();
        }

        private void toolStripButtonBalloonExcludeCircle_CheckedChanged(object sender, EventArgs e)
        {
            if (toolStripButtonBalloonExcludeCircle.Checked)
            {
                resetToolStripBalloon(toolStripButtonBalloonExcludeCircle);
                panelBalloonCircle.Visible = true;
                pageEditor.BalloonCircle.Enable(false);
            }
            else
            {
                panelBalloonCircle.Visible = false;
                pageEditor.BalloonCircle.Disable();
            }
            pageEditor.UpdatePage();
        }

        private void numericBalloonRadius_ValueChanged(object sender, EventArgs e)
        {
            pageEditor.BalloonCircle.Radius = (int)numericBalloonRadius.Value;
        }

        private void numericBalloonFillThreshold_ValueChanged(object sender, EventArgs e)
        {
            pageEditor.BalloonFill.Threshold = (int)numericBalloonFillThreshold.Value;
        }

        private void buttonDelete_Click(object sender, EventArgs e)
        {
            if (listBoxBalloons.SelectedIndex >= 0)
            {
                int i = listBoxBalloons.SelectedIndex;
                pageInfo.Balloons[i].Dispose();
                pageInfo.Balloons.RemoveAt(i);
                listBoxBalloons.Items.RemoveAt(i);
                if (i == listBoxBalloons.Items.Count)
                    i--;
                if (i >= 0)
                    listBoxBalloons.SelectedIndex = i;
                else
                {
                    balloon = null;
                    updateCurrentBalloon();
                }
                pageEditor.UpdatePage();
            }
        }

        private void listBoxBalloons_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (balloon != null)
                balloon.EndEdit();
            balloon = null;

            if (listBoxBalloons.SelectedIndex >= 0)
            {
                Balloon newBalloon = pageInfo.Balloons[listBoxBalloons.SelectedIndex];

                checkBoxFill.Checked = newBalloon.Fill != null;
                if (checkBoxFill.Checked)
                {
                    labelFill.BackColor = Color.FromArgb(255, (newBalloon.Fill as SolidBrush).Color);
                    numericFillOpacity.Value = (decimal)Math.Round((newBalloon.Fill as SolidBrush).Color.A/2.55);
                }
                checkBoxStroke.Checked = newBalloon.Stroke != null;
                if (checkBoxStroke.Checked)
                {
                    labelStroke.BackColor = Color.FromArgb(255, newBalloon.Stroke.Color);
                    numericStrokeOpacity.Value = (decimal)Math.Round(newBalloon.Stroke.Color.A/2.55);
                    numericStroke.Value = (decimal)newBalloon.Stroke.Width;
                }
                trackBarSmooth.Value = (int)Math.Round(16 - newBalloon.CurveSmooth/Math.PI*16);
                trackBarSmooth.Enabled = !newBalloon.IsReadOnly;
                trackBarStep.Value = 13 - (newBalloon.CurveStep - 1)/3;
                trackBarStep.Enabled = !newBalloon.IsReadOnly;

                balloon = newBalloon;
                updateCurrentBalloon();
            }
        }

        private void trackBarSmooth_ValueChanged(object sender, EventArgs e)
        {
            if (balloon != null)
            {
                balloon.CurveSmooth = Math.PI*(16 - trackBarSmooth.Value)/16;
                pageEditor.UpdatePage();
            }
        }

        private void trackBarStep_ValueChanged(object sender, EventArgs e)
        {
            if (balloon != null)
            {
                balloon.CurveStep = 1 + (13 - trackBarStep.Value)*3;
                pageEditor.UpdatePage();
            }
        }

        private void checkBoxFill_CheckedChanged(object sender, EventArgs e)
        {
            if (balloon != null)
            {
                if (checkBoxFill.Checked)
                    balloon.Fill = new SolidBrush(Color.FromArgb((int)Math.Round(2.55*(int)numericFillOpacity.Value), labelFill.BackColor));
                else
                    balloon.Fill = null;
                pageEditor.UpdatePage();
            }
        }

        private void checkBoxStroke_CheckedChanged(object sender, EventArgs e)
        {
            if (balloon != null)
            {
                if (checkBoxStroke.Checked)
                    balloon.Stroke = new Pen(Color.FromArgb((int)Math.Round(2.55*(int)numericStrokeOpacity.Value), labelStroke.BackColor), (float)numericStroke.Value);
                else
                    balloon.Stroke = null;
                pageEditor.UpdatePage();
            }
        }

        private void numericStroke_ValueChanged(object sender, EventArgs e)
        {
            if (balloon != null && checkBoxStroke.Checked)
            {
                balloon.Stroke = new Pen(Color.FromArgb((int)Math.Round(2.55*(int)numericStrokeOpacity.Value), labelStroke.BackColor), (float)numericStroke.Value);
                pageEditor.UpdatePage();
            }
        }

        private void labelFill_Click(object sender, EventArgs e)
        {
            colorDialog.Color = labelFill.BackColor;
            if (colorDialog.ShowDialog() == DialogResult.OK)
            {
                labelFill.BackColor = colorDialog.Color;
                if (balloon != null && checkBoxFill.Checked)
                {
                    balloon.Fill = new SolidBrush(Color.FromArgb((int)Math.Round(2.55*(int)numericFillOpacity.Value), labelFill.BackColor));
                    pageEditor.UpdatePage();
                }
            }
        }

        private void labelStroke_Click(object sender, EventArgs e)
        {
            colorDialog.Color = labelStroke.BackColor;
            if (colorDialog.ShowDialog() == DialogResult.OK)
            {
                labelStroke.BackColor = colorDialog.Color;
                if (balloon != null && checkBoxStroke.Checked)
                {
                    balloon.Stroke = new Pen(Color.FromArgb((int)Math.Round(2.55*(int)numericStrokeOpacity.Value), labelStroke.BackColor), (float)numericStroke.Value);
                    pageEditor.UpdatePage();
                }
            }
        }

        private void numericFillOpacity_ValueChanged(object sender, EventArgs e)
        {
            if (balloon != null && checkBoxFill.Checked)
            {
                balloon.Fill = new SolidBrush(Color.FromArgb((int)Math.Round(2.55*(int)numericFillOpacity.Value), labelFill.BackColor));
                pageEditor.UpdatePage();
            }
        }

        private void numericStrokeOpacity_ValueChanged(object sender, EventArgs e)
        {
            if (balloon != null && checkBoxStroke.Checked)
            {
                balloon.Stroke = new Pen(Color.FromArgb((int)Math.Round(2.55*(int)numericStrokeOpacity.Value), labelStroke.BackColor), (float)numericStroke.Value);
                pageEditor.UpdatePage();
            }
        }

        private void checkFillRestrict_CheckedChanged(object sender, EventArgs e)
        {
            updateCurrentBalloon();
        }
    }
}
